package com.bmob.lover.app.ext

import android.media.ThumbnailUtils
import android.provider.MediaStore
import com.bmob.lover.app.util.DeviceUtil
import com.google.gson.GsonBuilder
import com.bmob.lover.data.model.bean.BmobBean
import com.bmob.lover.data.model.bean.User
import com.hjq.toast.ToastUtils
import com.theone.mvvm.base.appContext
import rxhttp.wrapper.cahce.CacheMode
import rxhttp.wrapper.utils.getActualTypeParameter
import java.lang.reflect.Type

//  ┏┓　　　┏┓
//┏┛┻━━━┛┻┓
//┃　　　　　　　┃
//┃　　　━　　　┃
//┃　┳┛　┗┳　┃
//┃　　　　　　　┃
//┃　　　┻　　　┃
//┃　　　　　　　┃
//┗━┓　　　┏━┛
//    ┃　　　┃                  神兽保佑
//    ┃　　　┃                  永无BUG！
//    ┃　　　┗━━━┓
//    ┃　　　　　　　┣┓
//    ┃　　　　　　　┏┛
//    ┗┓┓┏━┳┓┏┛
//      ┃┫┫　┃┫┫
//      ┗┻┛　┗┻┛
/**
 * @author The one
 * @date 2021-05-06 13:20
 * @describe TODO
 * @email 625805189@qq.com
 * @remark
 */

fun <T : BmobBean> T.pointer(): T = setType("Pointer")

private fun <T : BmobBean> T.setType(type: String): T {
    return apply {
        __type = type
        className = if (this is User) {
            "_User"
        } else {
            this::class.java.simpleName
        }
    }
}

// 拿到带泛型Class<T>中T的类名
fun Class<*>.getTableName(index: Int = 0): String =
    getActualTypeParameter(this, index).getTableName()

// 拿到泛型T的类名
fun Type.getTableName(): String =
    toString().run {
       val name =  substring(lastIndexOf(".") + 1)
        if(name.equals("User")){
            "_User"
        }else{
            name
        }
    }

fun getCacheMode(isFirst: Boolean): CacheMode {
    return if (isFirst)
        CacheMode.READ_CACHE_FAILED_REQUEST_NETWORK
    else
        CacheMode.NETWORK_SUCCESS_WRITE_CACHE
}

fun Any.getExposeJson(): String {
    return GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(this)
}

fun Any.getObjectPostJson(vararg attrs: String): String {
    return toJsonWithoutAttr("__type", "objectId", "className", "createdAt", "updatedAt", *attrs)
}

fun Any.getObjectUpdateJson(vararg attrs: String): String {
    return getExposeJson().jsonWithoutAttr(
        "__type",
        "objectId",
        "className",
        "createdAt",
        "updatedAt",
        *attrs
    )
}

fun String.getCreatePostJson(vararg attrs: String): String {
    return getPostJson("__type", "objectId", "className", "createdAt", "updatedAt", *attrs)
}

fun String.getPostJson(vararg attrs: String): String {
    var placeholder = this
    for (att in attrs) {
        val old = equal(att, "")
        placeholder = placeholder.replace(",$old", "")
    }
    return placeholder
}

fun User?.getId(): String {
    return this?.objectId ?: ""
}

fun User?.equalIfExist(key: String): String {
    val id = this?.objectId
    return if (id?.isNotEmpty() == true)
        equal(key, id)
    else
        "\"$key\":${assembly(equal("\$exists", false))}"
}

fun or(vararg values: String): String =
    multiple("or", *values)

fun and(vararg values: String): String =
    multiple("and", *values)

private fun multiple(operation: String, vararg values: String): String {
    val sb = StringBuffer()
    values.forEach {
        if (it.isNotEmpty()) {
            sb.append(it)
            sb.append(",")
        }
    }
    sb.replace(sb.length - 1, sb.length, "")
    return "{\"\$$operation\":[${sb}]}"
}

fun equal(key: String, value: Int): String {
    return "\"$key\":$value"
}

fun exists(key:String,exist: Boolean): String {
    return "\"$key\":${assembly(equal("\$exists", exist))}"
}

fun equal(key: String, value: String): String {
    return "\"$key\":\"$value\""
}

fun equal(key: String, value: Boolean): String {
    return "\"$key\":$value"
}

fun <T : BmobBean> T.pointer(key: String): String {
    val nName = if (this is User) {
        "_User"
    } else {
        this::class.java.simpleName
    }
    return "{\"$key\":${assembly(
        equal("__type", "Pointer"), 
        equal("className", nName), 
        equal("objectId", objectId)
    )}}"
}

fun assembly(vararg values: String): String {
    val sb = StringBuffer()
    sb.append("{")
    values.forEach {
        if (it.isNotEmpty()) {
            sb.append(it)
            sb.append(",")
        }
    }
    sb.replace(sb.length - 1, sb.length, "")
    sb.append("}")
    return sb.toString()
}

fun User?.isTestAdmin(show: Boolean = true): Boolean {
    val isAdmin =
        this?.username == "admin"
    return if (isAdmin) {
        if (show)
            ToastUtils.show("测试账号不能进行此操作")
        true
    } else {
        false
    }
}


